// 多态
package main

import (
	"fmt"
)

type Walkable interface {
	walk()
}

type Cat struct {
}

func (c *Cat) walk() {
	fmt.Println("猫用4条腿走路！")
}

type Chicken struct {
}

func (c *Chicken) walk() {
	fmt.Println("鸡用2条腿走路！")
}

func main() {
	var w1, w2 Walkable
	w1 = new(Cat)
	w2 = new(Chicken)

	w1.walk()
	w2.walk()

	var c = Cat{}
	getType(c)
}

func getType(obj interface{}) {
	// 类型断言 x.(T) 其实就是判断 x 是否实现了 T 接口，如果实现了，就把 x 接口类型具体化为 T 类型
	// 如果 ok1 为 true，则 obj 转为 Cat 类型并保存为 v1
	v1, ok1 := obj.(Cat)
	fmt.Printf("check Cat, v:%v %v  \n", v1, ok1)

	v2, ok2 := obj.(Chicken)
	fmt.Printf("check Chicken, v:%v %v  \n", v2, ok2)

	v3, ok3 := obj.(int)
	fmt.Printf("check Chicken, v:%v %v  \n", v3, ok3)

	// obj.(type) 只能用于switch，用来判断obj的类型
	switch obj.(type) {
	case Cat:
		fmt.Println("this is Cat")
	case Chicken:
		fmt.Println("this is Chicken")
	default:
		fmt.Println("unknow")
	}
}
